home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 20 / Cream of the Crop 20 (Terry Blount) (1996).iso / os2 / bind493a.zip / named / ns_maint.c < prev    next >
C/C++ Source or Header  |  1995-12-22  |  27KB  |  1,102 lines

  1. #if !defined(lint) && !defined(SABER)
  2. static char sccsid[] = "@(#)ns_maint.c    4.39 (Berkeley) 3/2/91";
  3. static char rcsid[] = "$Id: ns_maint.c,v 8.11 1995/12/22 10:20:30 vixie Exp $";
  4. #endif /* not lint */
  5.  
  6. /*
  7.  * ++Copyright++ 1986, 1988
  8.  * -
  9.  * Copyright (c) 1986, 1988
  10.  *    The Regents of the University of California.  All rights reserved.
  11.  * 
  12.  * Redistribution and use in source and binary forms, with or without
  13.  * modification, are permitted provided that the following conditions
  14.  * are met:
  15.  * 1. Redistributions of source code must retain the above copyright
  16.  *    notice, this list of conditions and the following disclaimer.
  17.  * 2. Redistributions in binary form must reproduce the above copyright
  18.  *    notice, this list of conditions and the following disclaimer in the
  19.  *    documentation and/or other materials provided with the distribution.
  20.  * 3. All advertising materials mentioning features or use of this software
  21.  *    must display the following acknowledgement:
  22.  *     This product includes software developed by the University of
  23.  *     California, Berkeley and its contributors.
  24.  * 4. Neither the name of the University nor the names of its contributors
  25.  *    may be used to endorse or promote products derived from this software
  26.  *    without specific prior written permission.
  27.  * 
  28.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  29.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  30.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  31.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  32.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  33.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  34.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  35.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  36.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  37.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  38.  * SUCH DAMAGE.
  39.  * -
  40.  * Portions Copyright (c) 1993 by Digital Equipment Corporation.
  41.  * 
  42.  * Permission to use, copy, modify, and distribute this software for any
  43.  * purpose with or without fee is hereby granted, provided that the above
  44.  * copyright notice and this permission notice appear in all copies, and that
  45.  * the name of Digital Equipment Corporation not be used in advertising or
  46.  * publicity pertaining to distribution of the document or software without
  47.  * specific, written prior permission.
  48.  * 
  49.  * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
  50.  * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
  51.  * OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT
  52.  * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
  53.  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
  54.  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
  55.  * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  56.  * SOFTWARE.
  57.  * -
  58.  * --Copyright--
  59.  */
  60.  
  61. #include <sys/param.h>
  62. #include <sys/types.h>
  63. #include <sys/socket.h>
  64. #include <netinet/in.h>
  65. #include <arpa/inet.h>
  66. #include <arpa/nameser.h>
  67. #include <sys/wait.h>
  68. #include <stdio.h>
  69. #include <syslog.h>
  70. #include <signal.h>
  71. #include <errno.h>
  72. #include <sys/stat.h>
  73.  
  74. #include "named.h"
  75.  
  76. #ifdef USE_UTIME
  77. # include <utime.h>
  78. #endif
  79.  
  80. static int        xfers_running,    /* # of xfers running */
  81.             xfers_deferred,    /* # of needed xfers not run yet */
  82.             qserials_running,
  83.             alarm_pending,    /* flag */
  84.             nxfers __P((struct zoneinfo *, int));
  85.  
  86. static void        startxfer __P((struct zoneinfo *)),
  87.             abortxfer __P((struct zoneinfo *)),
  88.             addxfer __P((struct zoneinfo *)),
  89.             tryxfer __P((void));
  90.  
  91. #define    qserial_qfull()    (qserials_running == MAXQSERIAL)
  92.  
  93. #ifdef CLEANCACHE
  94. static time_t cache_time;
  95. #endif
  96. #ifdef XSTATS
  97. static time_t stats_time;
  98. #endif
  99. /*
  100.  * Invoked at regular intervals by signal interrupt; refresh all secondary
  101.  * zones from primary name server and remove old cache entries.  Also,
  102.  * ifdef'd ALLOW_UPDATES, dump database if it has changed since last
  103.  * dump/bootup.
  104.  */
  105. void
  106. ns_maint()
  107. {
  108.     register struct zoneinfo *zp;
  109.     int zonenum;
  110.  
  111.     gettime(&tt);
  112.  
  113.     dprintf(1, (ddt, "\nns_maint(); now %s", ctimel(tt.tv_sec)));
  114.  
  115.     alarm_pending = 0;
  116.     for (zp = zones, zonenum = 0; zp < &zones[nzones]; zp++, zonenum++) {
  117. #ifdef DEBUG
  118.         if (debug >= 2)
  119.             printzoneinfo(zonenum);
  120. #endif
  121.         if (tt.tv_sec >= zp->z_time && zp->z_refresh > 0) {
  122.             switch (zp->z_type) {
  123.  
  124.             case Z_CACHE:
  125.                 doachkpt();
  126.                 ns_refreshtime(zp, tt.tv_sec);
  127.                 break;
  128.  
  129.             case Z_SECONDARY:
  130. #ifdef STUBS
  131.             case Z_STUB:
  132. #endif
  133.                 if (zp->z_serial != 0 &&
  134.                     ((zp->z_lastupdate + zp->z_expire) <
  135.                      tt.tv_sec)
  136.                     ) {
  137.                     zp->z_serial = 0;
  138.                 }
  139.                 if (zp->z_flags &
  140.                     (Z_NEED_RELOAD|Z_NEED_XFER|Z_QSERIAL)) {
  141.                     ns_refreshtime(zp, tt.tv_sec);
  142.                     break;
  143.                 }
  144.                 if (zp->z_flags & Z_XFER_RUNNING) {
  145.                     abortxfer(zp);
  146.                     break;
  147.                 }
  148.                 qserial_query(zp);
  149.                 break;
  150. #ifdef ALLOW_UPDATES
  151.             case Z_PRIMARY:
  152.                 /*
  153.                  * Checkpoint the zone if it has changed
  154.                  * since we last checkpointed
  155.                  */
  156.                 if (zp->z_flags & Z_CHANGED) {
  157.                     zonedump(zp);
  158.                     ns_refreshtime(zp, tt.tv_sec);
  159.                 }
  160.                 break;
  161. #endif /* ALLOW_UPDATES */
  162.             }
  163.             gettime(&tt);
  164.         }
  165.     }
  166. #ifdef CLEANCACHE
  167.     if ((cache_time + cache_interval) <= tt.tv_sec) {
  168.         if (cache_time)
  169.             remove_zone(hashtab, 0, 0);
  170.         cache_time = tt.tv_sec;
  171.     }
  172. #endif
  173. #ifdef XSTATS
  174.     if (stats_time + stats_interval <= tt.tv_sec) {
  175.         if (stats_time)
  176.             ns_logstats();
  177.         stats_time = tt.tv_sec;
  178.     }
  179. #endif
  180.     if (!needmaint)
  181.         sched_maint();
  182.     dprintf(1, (ddt, "exit ns_maint()\n"));
  183. }
  184.  
  185. /*
  186.  * Find when the next refresh needs to be and set
  187.  * interrupt time accordingly.
  188.  */
  189. void
  190. sched_maint()
  191. {
  192.     register struct zoneinfo *zp;
  193.     struct itimerval ival;
  194. #ifdef    CLEANCACHE
  195.     time_t next_refresh = cache_time + cache_interval;
  196. #else
  197.     time_t next_refresh = 0;
  198. #endif
  199.     static time_t next_alarm;
  200.  
  201.     for (zp = zones; zp < &zones[nzones]; zp++)
  202.         if (zp->z_time != 0 &&
  203.             (next_refresh == 0 || next_refresh > zp->z_time))
  204.             next_refresh = zp->z_time;
  205.         /*
  206.      *  Schedule the next call to ns_maint.
  207.      *  Don't visit any sooner than maint_interval.
  208.      */
  209.     bzero((char *)&ival, sizeof ival);
  210.     if (next_refresh != 0) {
  211.         if (next_refresh == next_alarm && alarm_pending) {
  212.             dprintf(1, (ddt, "sched_maint: no schedule change\n"));
  213.             return;
  214.         }
  215.         /*
  216.          *  tv_sec can be an unsigned long, so we can't let
  217.          *  it go negative.
  218.          */
  219.         if (next_refresh < tt.tv_sec)
  220.             next_refresh = tt.tv_sec;
  221.         ival.it_value.tv_sec = next_refresh - tt.tv_sec;
  222.         if ((long) ival.it_value.tv_sec < maint_interval)
  223.             ival.it_value.tv_sec = maint_interval;
  224.         next_alarm = next_refresh;
  225.         alarm_pending = 1;
  226.     }
  227.     (void) setitimer(ITIMER_REAL, &ival, (struct itimerval *)NULL);
  228.     dprintf(1, (ddt, "sched_maint: Next interrupt in %lu sec\n",
  229.             (u_long)ival.it_value.tv_sec));
  230. }
  231.  
  232. /*
  233.  * Mark a zone "up to date" after named-xfer tells us this or we
  234.  * discover it through the qserial_*() logic.
  235.  */
  236. static void
  237. markUpToDate(zp)
  238.     struct zoneinfo *zp;
  239. {
  240.     struct stat f_time;
  241.  
  242.     zp->z_flags &= ~Z_SYSLOGGED;
  243.     zp->z_lastupdate = tt.tv_sec;
  244.     ns_refreshtime(zp, tt.tv_sec);
  245.     /*
  246.      * Restore Z_AUTH in case expired,
  247.      * but only if there were no errors
  248.      * in the zone file.
  249.      */
  250.     if ((zp->z_flags & Z_DB_BAD) == 0)
  251.         zp->z_flags |= Z_AUTH;
  252.     if (zp->z_source) {
  253. #if defined(USE_UTIME)
  254.         struct utimbuf t;
  255.  
  256.         t.actime = tt.tv_sec;
  257.         t.modtime = tt.tv_sec;
  258.         (void) utime(zp->z_source, &t);
  259. #else
  260.         struct timeval t[2];
  261.  
  262.         t[0] = tt;
  263.         t[1] = tt;
  264.         (void) utimes(zp->z_source, t);
  265. #endif /* USE_UTIME */
  266.     }
  267.     /* we use "stat" to set zp->z_ftime instead of just
  268.        setting it to tt.tv_sec in order to avoid any
  269.        possible rounding problems in utimes(). */
  270.     if (stat(zp->z_source, &f_time) != -1)
  271.         zp->z_ftime = f_time.st_mtime;
  272.     /* XXX log if stat fails? */
  273. }
  274.  
  275. /*
  276.  * Query for the serial number of a zone, so that
  277.  * we can check to see if we need to transfer it.
  278.  */
  279. void
  280. qserial_query(zp)
  281.     struct zoneinfo *zp;
  282. {
  283.     struct qinfo *qp;
  284.  
  285.     dprintf(1, (ddt,